﻿using SanJ.FreeCare.ObservationDefinitions;
using SanJ.FreeCare.ValueSets;
using SanJ.Infrastructure;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Services;

namespace SanJ.FreeCare.ConditionDefinitions
{
    public class ConditionDefinitionManager : DomainService
    {
        private readonly IConditionDefinitionRepository _conditionDefinitionRepository;
        public ConditionDefinitionManager(IConditionDefinitionRepository conditionDefinitionRepository)
        {
            _conditionDefinitionRepository = conditionDefinitionRepository;
        }
        public async Task<ConditionDefinition> CreateAsync(ConditionDefinition conditionDefinition)
        {
            conditionDefinition.Code = await GetNextChildCodeAsync(conditionDefinition.ParentId);
            if (conditionDefinition.ParentId == Guid.Empty)
            {
                conditionDefinition.ParentId = Guid.NewGuid();
            }
            if (conditionDefinition.IsVaild.IsNullOrEmpty())
            {
                conditionDefinition.IsVaild = VaildType.InVaild;
            }
            return await _conditionDefinitionRepository.InsertAsync(conditionDefinition);
        }
        public async Task CreatManysync(List<ConditionDefinition> conditionDefinitions)
        {
            foreach (var conditionDefinition in conditionDefinitions)
            {
                if (conditionDefinition.ParentId == Guid.Empty)
                {
                    conditionDefinition.ParentId = Guid.NewGuid();
                }
                if (conditionDefinition.IsVaild.IsNullOrEmpty())
                {
                    conditionDefinition.IsVaild = VaildType.InVaild;
                }
            }
        }
        public async Task<ConditionDefinition> UpdateAsync(Guid id, ConditionDefinition conditionDefinition)
        {
            return await _conditionDefinitionRepository.UpdateAsync(conditionDefinition);
        }
        public Task UpdateBatchAsync(List<ConditionDefinition> conditionDefinitions)
        {
            return _conditionDefinitionRepository.UpdateManyAsync(conditionDefinitions);
        }
        public async Task<List<ConditionDefinition>> GetListAsync()
        {
            return await _conditionDefinitionRepository.GetListAsync();
        }
        public async Task<List<ConditionDefinition>> GetVaildListAsync()
        {
            return await _conditionDefinitionRepository.GetListAsync(p => p.IsVaild == VaildType.Vaild);
        }
        public async Task<List<ConditionDefinition>> GetPageLisAsync(string filter, string sorting, int maxResultCount = int.MaxValue,
            int skipCount = 0)
        {
            return await _conditionDefinitionRepository.GetPageLisAsync(filter, sorting, maxResultCount, skipCount);
        }
        public async Task<long> GetCountAsync(string filter)
        {
            return await _conditionDefinitionRepository.GetCountAsync(filter);
        }
        public Task Delete(Guid id)
        {
            return _conditionDefinitionRepository.DeleteAsync(id);
        }
        private async Task<string> GetNextChildCodeAsync(Guid? patientId)
        {
            var lastChild = await GetLastChildOrNullAsync(patientId);
            if (lastChild != null)
            {
                return HierarchicalCodeManager.CalculateNextCode(lastChild.Code);
            }
            string? parentCode = null;
            if (patientId == null || patientId != Guid.Empty)
            {
                parentCode = null;
            }
            else
            {
                parentCode = (await GetByIdAsync(patientId)).Code;
            }
            return HierarchicalCodeManager.AppendCode(parentCode, HierarchicalCodeManager.CreateCode(1));
        }
        private async Task<ConditionDefinition> GetLastChildOrNullAsync(Guid? patientId)
        {
            var children = await this.GetListByPatientIdAsync(patientId);
            return children.OrderBy(c => c.Code).LastOrDefault();
        }
        public async Task<List<ConditionDefinition>> GetListByPatientIdAsync(Guid? patientId)
        {
            return await _conditionDefinitionRepository.GetListAsync(p => p.ParentId == patientId);
        }
        public async Task<ConditionDefinition> GetByIdAsync(Guid? id)
        {
            return (await _conditionDefinitionRepository.GetListAsync(p => p.Id == id)).FirstOrDefault();
        }
    }
}
